iOS Coding Standard (Swift)
1. Objective
To ensure all iOS applications developed at [Your Company Name] follow a consistent, high-quality, and maintainable coding approach that aligns with organizational and industry best practices.
2. Scope
This document applies to all iOS, iPadOS, and macOS development projects using Swift (and Objective-C for interoperability), developed in Xcode, and maintained under [Your Company Name]'s repositories.
3. Architecture & Project Structure
Adopt MVVM (Model-View-ViewModel), as it integrates seamlessly with both SwiftUI and UIKit (with Combine or async/await). Maintain a consistent project folder structure, grouped by feature:
AppName/ ├── Application/ // AppDelegate, SceneDelegate, Info.plist ├── Features/ // One folder per app feature (e.g., Profile, Home) │ ├── Home/ │ │ ├── Model/ // HomeModels.swift │ │ ├── View/ // HomeView.swift (SwiftUI) or HomeViewController.swift (UIKit) │ │ └── ViewModel/ // HomeViewModel.swift │ ├── Profile/ │ │ ├── Model/ │ │ ├── View/ │ │ └── ViewModel/ ├── Data/ │ ├── Network/ // APIService.swift, NetworkError.swift │ ├── Persistence/ // CoreData, SwiftData, KeychainService.swift │ └── Models/ // Shared data models (e.g., User.swift) ├── Utilities/ // Helpers, Extensions, Constants.swift ├── Resources/ // Assets.xcassets, Localizable.strings └── DI/ // Dependency Injection container (if used)
- Key Principle: Separate business logic from UI logic.
- Avoid "Massive View Controllers."
ViewControllers (UIKit)orViews(SwiftUI) should be "dumb" and only responsible for displaying data and forwarding user events to theViewModel.
4. Naming Conventions
Follow Apple's API Design Guidelines for clarity at the point of use.
| Element | Convention | Example |
|---|---|---|
| Types (Class, Struct, Enum) | UpperCamelCase |
UserProfileView, NetworkService |
| Variables & Functions | lowerCamelCase |
var userName: Stringfunc fetchUserData() |
| Constants (Global) | lowerCamelCase |
let maxRetryCount = 3 |
| Booleans | Prefixed with is, has, did |
var isUserLoggedIn: Bool |
@IBOutlet (UIKit) |
lowerCamelCase |
@IBOutlet var userNameLabel: UILabel |
@IBAction (UIKit) |
lowerCamelCase (verb first) |
@IBAction func didTapSubmitButton(_ sender: Any) |
Reference: Apple's API Design Guidelines
5. Code Formatting & Style
- Indentation: 4 spaces (or 2 if team agrees, but be consistent).
- Maximum line length: 120 characters (enforced by SwiftLint).
- Avoid unused imports, variables, or commented-out code.
- Add Swift-DocC comments
(///)for all public classes, methods, and complex logic. - Use
letinstead ofvarwherever possible for immutability. - Use
finalon classes not intended for subclassing to improve performance.
Learn more: Swift-DocC Documentation
6. UI/UX & Resource Management
- Use SwiftUI Stacks/Grids or Auto Layout (for UIKit) for flexible designs.
- No hardcoding.
- Text: Use
Localizable.stringsfor all user-facing text. - Colors/Images: Use the
Assets.xcassets catalog.
- Text: Use
- Use
privatefor@IBOutletand@IBActionto encapsulate view logic. - Follow accessibility guidelines (e.g.,
accessibilityLabel, dynamic type support).
Learn more: Using the Asset Catalog
7. Networking & Data Handling
- Use native
URLSessionwithasync/awaitfor all REST APIs.Combineis acceptable for reactive streams.Alamofireis acceptable for complex networking needs if approved.
- Use SwiftData (preferred for new projects) or Core Data for local database storage.
- Parse JSON using the
Codableprotocol. - Handle API responses using Swift's
Resulttype orasync throws. - Avoid network calls on the main thread. Use
Taskor await MainActor.runto update UI.
Learn more: Fetching data with URLSession and async/await
8. Error Handling & Logging
- Use Swift's error handling
(do-try-catch, throws)for failable operations. - Never use
print()for logging. - Use Apple's
OSLog (Logger)framework for all logging. - Swift
import OSLog
let logger = Logger(subsystem: "com.yourapp.feature", category:
"ViewModel")
logger.debug("Loading user profile...")
logger.error("Error loading user profile:
\(error.localizedDescription)")
OSLog logsare automatically managed (not shown in release builds) and viewable in the Console app.
Learn more: Logging in Swift with OSLog
9. Security & Performance
- Never store sensitive data (tokens, passwords, PII) in
UserDefaults. Use the Keychain services. - Use
[weak self]in closures to prevent retain cycles (memory leaks). - Set "Optimization Level" to
-O(Fastest, Smallest) in Release builds. - Use Instruments (Leaks, Time Profiler) to find and fix performance issues.
Learn more: Storing Data in the Keychain
10. Testing
- Write
XCTestUnit Tests for ViewModels, business logic, and utility functions. - Write
XCTestUI Tests for critical user flows. - Maintain at least 70% test coverage for core modules.
- Use protocol-based mocking and dependency injection to make code testable.
Learn more: Testing with XCTest
11. Automation & CI/CD Integration
- Integrate static analysis tools:
- SwiftLint: Enforces formatting and style rules.
- SwiftFormat: (Optional) Automatically formats code.
- Use Xcode's built-in "Analyze" tool to find potential bugs and leaks.
- CI/CD (e.g.,** Xcode Cloud**, GitHub Actions) should run
XCTestandSwiftLintand fail the build on violations.
Learn more: Integrating SwiftLint with Xcode
12. References
- The Swift Programming Language (Official Swift Book)
- Apple API Design Guidelines (The most important reference)
- Kodeco (formerly Ray Wenderlich) Style Guide (A popular community guide)